#ifndef _MY_BACKGROUND_H_
#define _MY_BACKGROUND_H_

#include <atomic>
#include <mutex>
#include <functional>
#include <string>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "my_linklist.h"


#define TASK_ARRIVED_EVENT	(1 << 0)    // 任务到达事件
#define INSTANCE_ALIVED     (1 << 1)    // 实例存在事件
#define CONFIG_NAME_LEN     8

using TaskWithArgFun = std::function<void(void*)>;
using FreeFun = std::function<void(void*)>;
using TaskWithoutArgFun = std::function<void(void)>;


/// @brief 后台任务管理类
class MyBackground {
private:
    struct Task {
        char            name[CONFIG_NAME_LEN];
        TaskWithArgFun  fn;
        void*           arg;
        FreeFun         free_fn;

        Task() : arg(nullptr) { name[0] = '\0'; }

        Task(const std::string& task_name, TaskWithArgFun fun, void* fn_arg = nullptr, FreeFun free_fun = nullptr)
            : fn(std::move(fun)), arg(fn_arg), free_fn(std::move(free_fun))
        {
            strncpy(name, task_name.c_str(), CONFIG_NAME_LEN - 1);
            name[CONFIG_NAME_LEN - 1] = '\0';
        }
   
        Task(const std::string& task_name, TaskWithoutArgFun fun, void* fn_arg = nullptr, FreeFun free_fn = nullptr)
            : arg(nullptr), free_fn(nullptr)
        {
            strncpy(name, task_name.c_str(), CONFIG_NAME_LEN - 1);
            name[CONFIG_NAME_LEN - 1] = '\0';

            fn = [func = std::move(fun)](void*) { func(); };
        }
   
        ~Task() {
            cleanup();
        }

        Task(const Task&) = delete;
        Task& operator=(const Task& other) = delete;

        // 移动构造函数
        Task(Task&& other) noexcept
            : fn(std::move(other.fn)), arg(other.arg), free_fn(std::move(other.free_fn))
        {
            strcpy(name, other.name);
            other.name[0] = '\0';
            other.fn = nullptr;
            other.arg = nullptr;
            other.free_fn= nullptr;
        }
        Task& operator=(Task&& other) noexcept {
            if (this != &other) {
                cleanup();

                strcpy(name, other.name);
                fn = std::move(other.fn);
                arg = other.arg;
                free_fn = std::move(other.free_fn);
                
                other.name[0] = '\0';
                other.fn = nullptr;
                other.arg = nullptr;
                other.free_fn= nullptr;
            }
            return *this;
        }

        inline void execute() const {
            if(fn) {
                fn(arg);
            }
        }

        private:
            void cleanup() {
                if (free_fn && arg) {
                    free_fn(arg);
                    arg = nullptr;
                }
            }
    };
public:
    static MyBackground& GetInstance() {
        static MyBackground background;
        return background;
    }

    size_t Clear(const std::string& name);
    bool Schedule(TaskWithArgFun fn, const std::string& task_name="", void* arg=nullptr, FreeFun free_fn=nullptr);
    bool Schedule(TaskWithoutArgFun fn, const std::string& task_name="");
    size_t  GetBackgroundTasks() const;
    void PrintBackgroundInfo();

private:

    MyBackground();
    ~MyBackground();

    MyBackground(const MyBackground&) = delete;
    MyBackground& operator=(const MyBackground&) = delete;

    void BackgroundHandler();
    
    mutable std::mutex  mutex_;
    size_t              max_tasks_count_;       // 历史最多任务数量
    std::atomic<bool>   clear_flag_{false};     // 清除后台标志
    TaskHandle_t        background_{nullptr};   // 后台任务句柄
    EventGroupHandle_t  event_group_{nullptr};  // 事件组
    MyList<Task, CONFIG_MAX_BACKGROUND_TASKS>   task_list_;
};

#endif
